*Replication Code for "Candidate Extremism and Voter Roll-Off in U.S. House Elections
*Michael G. Miller, Legislative Studies Quarterly 2021

use roll_off_replication.dta,clear

***TABLE 1 (Fixed Effects Coefficients Shown in Table A5)
*Interaction Variables were pre-coded to fool outreg2 for easier table-making.
*Original coding is preserved here

*Model 1

reg con_ro polarization log_texp quality open, cluster(g)

*Model 2
reg con_ro polarization log_texp quality open i.st_id i.year, cluster(g)
est store m2

*Model 3
reg con_ro polarization log_texp quality open pres_ext, cluster(g)

*Model 4
reg con_ro polarization log_texp quality open pres_ext i.st_id i.year, cluster(g)

*Model 5
reg con_ro polarization log_texp quality open pres_ext pres_pol, cluster(g)

*Model 6
reg con_ro polarization log_texp quality open pres_ext pres_pol i.st_id i.year, cluster(g)


*Figure 1

est restore m2

*Mean and SD Estimates
sum polarization if con_ro!=. & log_texp!=. & quality!=. & open!=.

#delimit ;
margins, at(polarization=(0.669 1.302 1.935 2.568 3.201));
marginsplot, 
title("") 
ytitle("Predicted Roll-Off") 
ylabel(3.5(.5)5, gmax gmin)
xtitle("Distance Between Candidate CF Scores")
xlabel(0.669 "-2 SD" 1.302 "-1 SD" 1.935 "Mean" 2.568 "+1 SD" 3.201 "+2 SD")
name(polarization, replace) graphregion(color(white))  
recast(scatter)
plot1opts(ms(square))
plotr(m(large));
#delimit cr




***TABLE 2 (Fixed Effects Coefficients Shown in Table A6)

*Model 7

reg con_ro cfscore_r cfscore_d log_texp quality open,  cluster(g)

*Model 8
reg con_ro cfscore_r cfscore_d log_texp quality open i.st_id i.year, cluster(g)

*Model 9
reg con_ro cfscore_r cfscore_d log_texp quality open pres_dem_perc, cluster(g)

*Model 10
reg con_ro cfscore_r cfscore_d log_texp quality open pres_dem_perc i.st_id i.year, cluster(g)
est store m10

*Model 11
reg con_ro cfscore_r cfscore_d log_texp quality open pres_dem_perc cf_int r_ext d_ext, cluster(g)

*Model 12
reg con_ro cfscore_r cfscore_d log_texp quality open pres_dem_perc cf_int r_ext d_ext i.st_id i.year, cluster(g)



*Figure 2
est restore m10
#delimit ;
margins, at(cfscore_r=(.986) cfscore_d=(-1.961 -1.452 -0.943 -0.434 0.075));
marginsplot, 
title("Democrats", size(large)) 
ytitle("Predicted Roll-Off at Opponent Mean Cfscore", size(large)) 
ylabel(3.5(.5)5, gmax gmin labsize(large))
xtitle("Candidate Cfscores", size(large))
xlabel(-1.961 `" "2 SD" "To Pole" "' -1.452 `" "1 SD" "To Pole" "' -.943 "Mean" -0.434 `" "1 SD" "to Center" "' 0.075 `" "2 SD" "to Center" "', labsize(large))
name(dems, replace) graphregion(color(white))  
plot1opts(ms(square))
recast(scatter)
plotr(m(large));
#delimit cr

#delimit ;
margins, at(cfscore_d=(-.943) cfscore_r=(0.098 0.542 0.986 1.430 1.874));
marginsplot, 
title("Republicans", size(large)) 
ytitle("") 
ylabel(3.5(.5)5, gmax gmin labsize(large))
xtitle("Candidate Cfscores", size(large))
xlabel(0.098 `" "2 SD" "To Center" "' 0.542 `" "1 SD" "To Center" "' 0.986  "Mean" 1.430 `" "1 SD" "to Pole" "' 1.874 `" "2 SD" "to Pole" "', labsize(large))
name(gop, replace) graphregion(color(white))  
plot1opts(ms(square))
recast(scatter)
plotr(m(large));
#delimit cr

graph combine (dems gop), iscale(*.74)

*Figure 3

reg con_ro c.cfscore_r##c.cfscore_d log_texp quality open c.pres_dem_perc##c.cfscore_d c.pres_dem_perc##c.cfscore_r i.st_id i.year, cluster(g)


#delimit ;
margins, at(cfscore_d=(-4(1)0) cfscore_r=(0.098 0.542 0.986 1.430 1.874));
marginsplot, 
title("") 
ytitle("Predicted Roll-Off", size(large)) 
ylabel(0(1)6, gmax gmin labsize(large))
xlabel(-4(1)0, labsize(large))
xtitle("Democratic Candidate Cfscores", size(large))
name(dem2, replace) graphregion(color(white))  
ciopts(color(*.2))
legend(pos(6) cols(2) order (1 "R 2 SD to Center" 2 "R 1 SD to Center" 3 "R At Mean" 4 "R 1 SD to Pole" 5 "R 2 SD to Pole") size(large))
noci
plotr(m(large));
#delimit cr



#delimit ;
margins, at(cfscore_r=(0(1)4) cfscore_d=(0.075 -0.434 -0.943 -1.452 -1.961));
marginsplot, 
title("") 
ytitle("Predicted Roll-Off", size(large)) 
ylabel(0(1)6, gmax gmin labsize(large))
xlabel(0(1)4, labsize(large))
xtitle("Republican Candidate Cfscores", size(large))
name(gop2, replace) graphregion(color(white))  
ciopts(color(*.2))
legend(pos(6) cols(2) order (1 "D 2 SD to Pole" 2 "D 1 SD to Pole" 3 "D At Mean" 4 "D 1 SD to Center" 5 "D 2 SD to Center") size(large))
noci
plotr(m(large));
#delimit cr

graph combine (dem2 gop2), iscale(*.74)



reg con_ro polarization log_texp quality open pres_ext



*Figure 4
reg gop_vote_perc c.cfscore_r##c.cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r c.pres_dem_perc##c.cfscore_d c.pres_dem_perc##c.cfscore_r i.st_id i.year, cluster(g)

#delimit ;
margins, at(cfscore_d=(-4(1)0) pres_dem_perc=(24.17 37.46 50.75 64.04 77.33));
marginsplot, 
title("") 
ytitle("Republican Share of 2-Party Vote", size(vlarge) margin(0 8 0 0)) 
ylabel(.2(.1).8, gmax gmin labsize(vlarge))
xlabel(-4(1)0, labsize(vlarge))
xtitle("Democratic House Candidate Cfscores", size(vlarge))
name(gopvote1, replace) graphregion(color(white))  
ciopts(color(*.2))
legend(pos(6) cols(5) title("Dem. Pres. Vote Perc.", size(vlarge)) order (1 "24.2%" 2 "37.5%" 3 "50.8%" 4 "64.0%" 5 "73.3%") size(vlarge))
noci
yline(.5, lstyle(dot))
plotr(m(vlarge));
#delimit cr



#delimit ;
margins, at(cfscore_r=(0(1)4) pres_dem_perc=(24.17 37.46 50.75 64.04 77.33));
marginsplot, 
title("") 
ytitle("Republican Share of 2-Party Vote", size(vlarge) margin(0 8 0 0)) 
ylabel(.2(.1).8, gmax gmin labsize(vlarge))
xlabel(0(1)4, labsize(vlarge))
xtitle("Republican House Candidate Cfscores", size(vlarge))
name(gopvote2, replace) graphregion(color(white))  
ciopts(color(*.2))
legend(pos(6) cols(5) title("Dem. Pres. Vote Perc.", size(vlarge)) order (1 "24.2%" 2 "37.5%" 3 "50.8%" 4 "64.0%" 5 "73.3%") size(vlarge))
noci
yline(.5, lstyle(dot))
plotr(m(vlarge));
#delimit cr

graph combine (gopvote1 gopvote2), iscale(*.6)



*Figure 5

use votes_replication.dta,clear

#delimit ;
graph hbar mean, over(v1, sort(n))
yline(13406, lp(dash))
title("")
legend(off)
text("")
;
#delimit cr

*Table A1
use roll_off_replication.dta,clear

#delimit ;
sum con_ro polarization cfscore_r cfscore_d log_texp quality open pres_dem_perc pres_ext
if  con_ro!=. &
polarization!=. &
cfscore_r!=. &
cfscore_d!=. &
log_texp!=. &
quality!=. &
open!=. &
pres_ext!=. &
pres_dem_perc!=. & 
st_id!=. &
year!=. &
g!=.
;
#delimit cr



****RD

use rd_data.dta,clear

*set cutoff for extremism
sum absdist, d
gl cutoff = r(p50)

sum absdist if democrat==1, d
gen d_cut= r(p50)
gen d_above=absdist>d_cut

sum absdist if democrat==0, d
gen r_cut= r(p50)
gen r_above=absdist>r_cut

sort id

quietly by id:  gen dup = cond(_N==1,0,_n)

gen two_extreme=dup==1 & d_above==1 & r_above==1

gen rv_plot=rv*100

*Figure A1

*Overall
rdplot con_ro rv_plot, p(2) graph_options(ylabel(-15(5)15) legend(off) xtitle("Extremist Primary Margin") ytitle("Roll-Off")) ci(95) shade genvars p(2)
drop rdplot_id-rdplot_hat_y

*Table A2
*Columns 1-4 examine vote share
* column 1
reg vote_general treat rv treat_rv  if abs(rv)<0.1 & absdist>$cutoff, cluster(g)

* column 2
reg vote_general treat rv rv2 rv3 if absdist>$cutoff, cluster(g)

* column 3
reg vote_general treat rv rv2 rv3 rv4 rv5 if absdist>$cutoff, cluster(g)

* column 4
rdrobust vote_general rv if absdist>$cutoff, vce(cluster g)

*Columns 5-8 examine roll-off
* column 5
reg con_ro treat rv treat_rv  if abs(rv)<0.1 & absdist>$cutoff, cluster(g)

* column 6
reg con_ro treat rv rv2 rv3 if absdist>$cutoff, cluster(g)

* column 7
reg con_ro treat rv rv2 rv3 rv4 rv5 if absdist>$cutoff, cluster(g)

* column 8
rdrobust con_ro rv if absdist>$cutoff, vce(cluster g)


*Table A3

* column 1
reg con_ro treat rv treat_rv  if abs(rv)<0.1 & absdist>$cutoff & two_extreme==0, cluster(g)


* column 2
reg con_ro treat rv rv2 rv3 if absdist>$cutoff & two_extreme==0, cluster(g)


* column 3
reg con_ro treat rv rv2 rv3 rv4 rv5 if absdist>$cutoff & two_extreme==0, cluster(g)


* column 4
rdrobust con_ro rv if absdist>$cutoff & two_extreme==0, vce(cluster g)

***Table A4

use roll_off_replication.dta,clear

*Model 1

reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r pres_dem_perc,  cluster(g)

*Model 2
reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r pres_dem_perc i.st_id i.year, cluster(g)

*Model 3
reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r pres_dem_perc, cluster(g)

*Model 4
reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r pres_dem_perc i.st_id i.year, cluster(g)

*Model 5
reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r cf_int c.pres_dem_perc##c.cfscore_d c.pres_dem_perc##c.cfscore_r , cluster(g)

*Model 6
reg gop_vote_perc cfscore_r cfscore_d gop_fund_perc dem_incumbent rep_incumbent quality_d quality_r pres_dem_perc cf_int c.pres_dem_perc##c.cfscore_d c.pres_dem_perc##c.cfscore_r i.st_id i.year, cluster(g)





















